package com.yycx.module.system.provider.service.impl;


import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.base.handler.BaseCheckAuthHandler;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.mybatis.base.service.impl.BaseServiceImpl;
import com.yycx.common.mybatis.model.ResultBody;
import com.yycx.common.mybatis.query.CriteriaDelete;
import com.yycx.common.mybatis.query.CriteriaQuery;
import com.yycx.common.mybatis.query.CriteriaSave;
import com.yycx.common.security.OpenHelper;
import com.yycx.module.system.client.entity.SysCompany;
import com.yycx.module.system.client.entity.SysDept;
import com.yycx.module.system.provider.mapper.SysDeptMapper;
import com.yycx.module.system.provider.service.SysDeptService;
import org.checkerframework.common.subtyping.qual.Bottom;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * 部门 实现类
 *
 * @author flyme
 * @date 2019-07-05
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysDeptServiceImpl extends BaseServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {

    @Autowired(required = false)
    private BaseCheckAuthHandler baseCheckAuthHandler;

    @Override
    public ResultBody beforeListEntityMap(CriteriaQuery<SysDept> cq, SysDept dept, EntityMap requestMap) {
        cq.select(SysDept.class, "*");
        return super.beforeListEntityMap(cq, dept, requestMap);
    }

    @Override
    public ResultBody beforePageList(CriteriaQuery<SysDept> cq, SysDept dept, EntityMap requestMap) {
        cq.select(SysDept.class, "*");
        return super.beforePageList(cq, dept, requestMap);
    }


    @Override
    public ResultBody beforeAdd(CriteriaSave cs, SysDept dept, EntityMap extra) {
        Long companyId = FlymeUtils.isNotEmpty(dept.getCompanyId()) ? dept.getCompanyId() : OpenHelper.getCompanyId();
        dept.setCompanyId(companyId);
        dept.setIsLeaf(1);
        if (FlymeUtils.isNotEmpty(baseCheckAuthHandler)) {
            Long count = countByCompanyId(companyId);
            Boolean tag = baseCheckAuthHandler.checkDeptCount(count.intValue());
            if (!tag) {
                return ResultBody.failed("添加失败:已达最大授权数量");
            }
        }
        return ResultBody.ok();
    }

    @Override
    public ResultBody afterAdd(CriteriaSave cs, SysDept dept, EntityMap extra) {
        Long parentId = dept.getParentId();
        if (FlymeUtils.isNotEmpty(parentId) && !parentId.equals(0L)) {
            SysDept parentDept = getById(parentId);
            parentDept.setIsLeaf(0);
            parentDept.updateById();
        }
        return super.afterAdd(cs, dept, extra);
    }

    @Override
    public List<EntityMap> deptTreeList(Long parentId, Long companyId) {
        CriteriaQuery cq = new CriteriaQuery(SysDept.class);
        cq.select(SysDept.class, "deptId as id", "deptName as label", "parentId", "isLeaf", "disabled", "icon");
        cq.eq("parentId", parentId);
        cq.eq("companyId", companyId);
        List<EntityMap> deptList = selectEntityMap(cq);
        return deptList;
    }

    @Override
    public ResultBody beforeDelete(CriteriaDelete<SysDept> cd) {
        Serializable id = cd.getIdValue();
        if (FlymeUtils.isNotEmpty(id)) {
            Long childCount = countByParentId(id);
            if (childCount > 0) {
                return ResultBody.failed("删除失败:已存在下级部门");
            }
        }
        return super.beforeDelete(cd);
    }


    @Override
    public Long countByParentId(Serializable deptId) {
        CriteriaQuery cq = new CriteriaQuery(SysDept.class);
        cq.eq(true, "parentId", deptId);
        return count(cq);
    }

    @Override
    public Long countByCompanyId(Serializable companyId) {
        CriteriaQuery cq = new CriteriaQuery(SysDept.class);
        cq.eq(true, "companyId", companyId);
        return count(cq);
    }


    @Override
    public List<EntityMap> selectDeptByUserId(Long userId) {
        CriteriaQuery cq = new CriteriaQuery(SysDept.class);
        cq.select(SysDept.class, "*");
        cq.eq(true, "bud.userId", userId);
        cq.createJoin("com.yycx.module.admin.client.entity.BaseUserDept").setMainField("deptId").setJoinField("deptId");
        return selectEntityMap(cq);
    }

    @Override
    public List<Long> selectDeptByUserId(Long userId, Long companyId) {
        List<Long> result = new ArrayList<>();
        CriteriaQuery cq = new CriteriaQuery(SysDept.class);
        cq.select(SysDept.class, "deptId");
        cq.eq(true, "bud.userId", userId);
        cq.eq(true, "dept.companyId", companyId);
        cq.createJoin("com.yycx.module.admin.client.entity.BaseUserDept").setMainField("deptId").setJoinField("deptId");
        List<EntityMap> list = selectEntityMap(cq);
        if (FlymeUtils.isNotEmpty(list)) {
            for (EntityMap entityMap : list) {
                Long deptId = entityMap.getLong("deptId");
                result.add(deptId);
            }
        }
        return result;
    }

    @Override
    public List<EntityMap> treeByUserId(Long userId, Long parentId, Long companyId) {
        CriteriaQuery cq = new CriteriaQuery(SysDept.class);
        cq.select(SysDept.class, "deptId as id", "deptName as label", "parentId", "isLeaf", "disabled", "icon");
        cq.eq("parentId", parentId);
        cq.eq("companyId", companyId);
        cq.eq(true, "bud.userId", userId);
        cq.createJoin("com.yycx.module.admin.client.entity.BaseUserDept").setMainField("deptId").setJoinField("deptId");
        return selectEntityMap(cq);
    }


}
